﻿namespace GameToolkit.BehaviourTree
{

    /// <summary>
    /// 装饰节点
    /// </summary>
    public abstract partial class Decoration : BehaviourTreeObject
    {
        ExecutableEntry mAttachedNode;
        public ExecutableEntry AttachedNode => mAttachedNode;

        internal override void InitializeSelf(CreateBehaviourTreeContext context)
        {
            base.InitializeSelf(context);
            if (context.parent is ExecutableEntry node)
                mAttachedNode = node;
            else if (context.parent is Decoration decor)
                mAttachedNode = decor.mAttachedNode;

            //UnityEngine.Debug.Assert(mAttachedNode != null, $"<{GetType().Name}> missing attached node.({context.player.Name})");
        }

        internal override void InvokeCreateRecursive(BehaviourTreePlayer player)
        {
            OnCreate(player);
        }
        internal override void InvokeDestroyRecursive(BehaviourTreePlayer player)
        {
            OnDestroy(player);
        }
    }

    /// <summary>
    /// 行为树条件
    /// </summary>
    public abstract partial class Condition : Decoration, IInterruptionSource
    {
        int mCacheId;
        bool mCachedTrue;

        NodeState IInterruptionSource.GetInterruptResult(BehaviourTreePlayer player)
        {
            if(mCacheId != player.UpdateId)
            {
                mCacheId = player.UpdateId;
                mCachedTrue = IsTrue(player);
            }
            return mCachedTrue ? NodeState.Running : NodeState.Failed;
        }

        NodeState IInterruptionSource.GetNotInterruptResult(BehaviourTreePlayer player)
        {
            if (mCacheId != player.UpdateId)
            {
                mCacheId = player.UpdateId;
                mCachedTrue = IsTrue(player);
            }
            return mCachedTrue ? NodeState.Failed : NodeState.Running;
        }
    }

}
